import time
import sys
from Fingerprint.util import *
import numpy as np
from obspy import read
from obspy.core import UTCDateTime


def write_timestamp(t, idx1, idx2, starttime, ts_file):
    fp_timestamp = np.asarray([t[int(np.mean((idx1[j], idx2[j])))] for j in range(len(idx1))])
    for ts in fp_timestamp:
        ts_file.write((starttime + datetime.timedelta(seconds=ts)).strftime('%y-%m-%dT%H:%M:%S.%f') + '\n')


def normalize_and_fingerprint(haar_images, fp_file):
    std_haar_images = feats.standardize_haar(haar_images, type='MAD')
    binaryFingerprints = feats.binarize_vectors_topK_sign(std_haar_images, K=params['fingerprint']['k_coef'])
    # 写入文件
    b = np.packbits(binaryFingerprints)
    fp_file.write(b.tobytes())


def init_MAD_stats(mad_fname):
    ntimes = get_ntimes(params)
    feats.haar_medians = np.zeros(params['fingerprint']['nfreq'] * ntimes)
    feats.haar_absdevs = np.zeros(params['fingerprint']['nfreq'] * ntimes)
    f = open(mad_fname, 'r')
    for i, line in enumerate(f.readlines()):
        nums = line.split(',')
        feats.haar_medians[i] = float(nums[0])
        feats.haar_absdevs[i] = float(nums[1])
    f.close()


if __name__ == '__main__':
    t_start = time.time()
    fname = sys.argv[1]
    print(fname)
    param_json = sys.argv[2]
    # fname = '../data/Deci5.Pick.19991015130000.CI.CDY.EHZ.sac'  # print(fname[8:])
    # param_json = '../data/fp_input_CI_CDY_EHZ.json'
    params = get_params(param_json)
    print(fname)
    print(params)

    feats = init_feature_extractor(params)
    # print(feats.__dict__)

    mad_name = get_mad_fname()
    print(mad_name)
    init_MAD_stats(mad_name)

    fp_folder, ts_folder = get_fp_ts_folders(params)
    print(fp_folder)
    print(ts_folder)
    init_folder([fp_folder, ts_folder])

    # 读取mseed
    st = read(fname)
    # print(st[0])

    ts_file = open(ts_folder + get_ts_fname(fname[8:]), 'w')
    fp_file = open(fp_folder + get_fp_fname(fname[8:]), 'wb')
    time_padding = get_partition_padding(params)
    min_fp_length = get_min_fp_length(params)

    for i in range(len(st)):
        starttime = datetime.datetime.strptime(str(st[i].stats.starttime), '%Y-%m-%dT%H:%M:%S.%fZ')
        endtime = datetime.datetime.strptime(str(st[i].stats.endtime), '%Y-%m-%dT%H:%M:%S.%fZ')
        # 如果该条数据长度小于一个spectrogram窗口长度，忽略
        if endtime - starttime < datetime.timedelta(seconds=min_fp_length):
            continue

        s = starttime

        # 为每个partition产生并输出fp
        while endtime - s > datetime.timedelta(seconds=min_fp_length):
            dt = datetime.timedelta(seconds=params['performance']['partition_len'])
            e = min(s + dt, endtime)
            e_padding = min(s + dt + time_padding, endtime)
            partition_st = st[i].slice(UTCDateTime(s.strftime('%Y-%m-%dT%H:%M:%S.%f')),
                                       UTCDateTime(e_padding.strftime('%Y-%m-%dT%H:%M:%S.%f')))
            # 短时傅立叶变换和小波变换(slice后的分区数据)
            haar_images, nWindows, idx1, idx2, Sxx, t = feats.data_to_haar_images(partition_st.data)
            # 将fp的时间戳写入文件
            write_timestamp(t, idx1, idx2, s, ts_file)
            # 以8小时为间隔标准化并输出fp
            normalize_and_fingerprint(haar_images, fp_file)
            s = e
    ts_file.close()
    fp_file.close()

    t_end = time.time()
    print("Binary fingerprints took: %.2f seconds" % (t_end - t_start))